package top.lixunda.demo.seata.common.controller;

import com.sun.istack.internal.NotNull;
import lombok.Getter;
import lombok.ToString;
import top.lixunda.demo.seata.common.function.Callback;
import top.lixunda.demo.seata.common.function.ThreeConsumer;

import java.util.function.Consumer;


/**
 * @author LiXunda
 * @version time:2019/8/4 11:24
 */
@SuppressWarnings({"WeakerAccess", "unchecked", "unused"})
@Getter
@ToString
public class MessageObject<T> {
    /**
     * 状态码
     * 1xx 临时响应
     * 2xx 成功
     * 3xx 重定向
     * 4xx 请求错误，客户端请求或参数错误
     * 5xx 服务器错误
     * x51-x99 通用异常占用，自定义异常尽量使用x01-x50
     */
    private int code;

    /**
     * 请求描述消息
     */
    private String msg;

    /**
     * 泛型数据对象
     */
    private T object;

    /**
     * 成功
     */
    public static final int CODE_SUCCESS = 200;

    public MessageObject<T> setCode(int code) {
        this.code = code;
        return this;
    }

    public MessageObject<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public MessageObject<T> setObject(T object) {
        this.object = object;
        return this;
    }

    public boolean isSuccess() {
        return this.code == 200;
    }

    public static <T> MessageObject<T> success(@NotNull String msg, T object) {
        return newInstance().setCode(200).setMsg(msg).setObject(object);
    }

    public static MessageObject<Object> success(@NotNull String msg) {
        return success(msg, null);
    }

    public static <T> MessageObject<T> success(Class<T> tClass, @NotNull String msg) {
        return success(msg, null);
    }

    public static <T> MessageObject<T> success(T object) {
        return success("操作成功", object);
    }

    public static MessageObject<Boolean> successBoolean() {
        return success("操作失败", true);
    }

    public static MessageObject<Boolean> successBoolean(String msg) {
        return success(msg, true);
    }

    public static <T> MessageObject<T> error(@NotNull String msg, T object) {
        return newInstance().setCode(400).setMsg(msg).setObject(object);
    }

    public static <T> MessageObject<T> error(@NotNull String msg) {
        return error(msg, null);
    }

    public static <T> MessageObject<T> error(Class<T> tClass, @NotNull String msg) {
        return error(msg, null);
    }

    public static MessageObject<Boolean> errorBoolean() {
        return success("操作失败", false);
    }

    public static MessageObject<Boolean> errorBoolean(String msg) {
        return success(msg, false);
    }

    public static MessageObject newInstance() {
        return new MessageObject();
    }

    public static <T> MessageObject<T> newInstance(Class<T> tClass) {
        return new MessageObject();
    }

    public MessageObject<T> ifSuccess(Consumer<T> consumer) {
        if (this.getCode() == CODE_SUCCESS && consumer != null) {
            consumer.accept(this.getObject());
        }
        return this;
    }

    public MessageObject<T> ifSuccess(Callback consumer) {
        if (this.getCode() == CODE_SUCCESS && consumer != null) {
            consumer.accept();
        }
        return this;
    }

    public MessageObject<T> ifSuccessBoolean(Callback consumer) {
        if (this.getCode() == CODE_SUCCESS && this.getObject() instanceof Boolean && this.getObject() != null
                && this.getObject().equals(true) && consumer != null) {
            consumer.accept();
        }
        return this;
    }

    public MessageObject<T> ifError(ThreeConsumer<Integer, String, T> consumer) {
        if (this.getCode() != CODE_SUCCESS && consumer != null) {
            consumer.accept(this.getCode(), this.getMsg(), this.getObject());
        }
        return this;
    }

    public MessageObject<T> ifError(Callback consumer) {
        if (this.getCode() != CODE_SUCCESS && consumer != null) {
            consumer.accept();
        }
        return this;
    }

    public MessageObject<T> ifErrorBoolean(Callback consumer) {
        if (this.getCode() != CODE_SUCCESS && this.getObject() instanceof Boolean && this.getObject() != null
                && this.getObject().equals(false) && consumer != null) {
            consumer.accept();
        }
        return this;
    }

    public MessageObject<T> dealWith(ThreeConsumer<Integer, String, T> consumer) {
        if (consumer != null) {
            consumer.accept(this.getCode(), this.getMsg(), this.getObject());
        }
        return this;
    }

}
